import { WorkerManager } from "../tools/WorkerManager";
import { MessageConstant } from "../tools/WorkerMessageConstant";
export const BmpConvertSDKVersion = "2.0.0-beta1";

export enum BmpConvertType {
    /**
     * 695N图像转换算法 - RGB
     */
    TYPE_695N_RBG = 0,
    /**
     * 701N图像转换算法 - RGB
     */
    TYPE_701N_RGB = 1,
    /**
     * 701N图像转换算法 - ARGB
     */
    TYPE_701N_ARGB = 2,
    /**
     * 701N图像转换算法 - RGB & 不打包封装
     */
    TYPE_701N_RGB_NO_PACK = 3,
    /**
     * 701N图像转换算法 - ARGB & 不打包封装
     */
    TYPE_701N_ARGB_NO_PACK = 4,
    /**
     * 707N图像转换算法 - RGB
     */
    TYPE_707N_RGB = 5,
    /**
     * 707N图像转换算法 - ARGB
     */
    TYPE_707N_ARGB = 6,
    /**
     * 707N图像转换算法 - RGB & 不打包封装
     */
    TYPE_707N_RGB_NO_PACK = 7,
    /**
     * 707N图像转换算法 - ARGB & 不打包封装
     */
    TYPE_707N_ARGB_NO_PACK = 8
}
export class ConvertParam {
    /**
  * 自动选取压缩后最小的格式，ARGB8565或者ARGB8888
  */
    public static readonly FORMAT_AUTO = 0;
    /**
     * 指定输出ARGB8565格式
     * <p>
     *     若算法是RGB算法，会变成指定输出RGB565格式
     * </p>
     */
    public static readonly FORMAT_ARGB_8565 = 1;
    /**
     * 指定输出ARGB8888格式
     * <p>
     *     若算法是RGB算法，会变成指定输出RGB888格式
     * </p>
     */
    public static readonly FORMAT_ARGB_8888 = 2;
    /**
     * 编码格式
     */
    format = ConvertParam.FORMAT_AUTO;

}
export class ConversionResult {
    /**
     * 结果码
     */
    result: number | undefined;
    /**
     * 算法类型
     */
    algorithm: number | undefined;
    /**
     * 图像格式
     */
    pixel_format: number | undefined;
    /**
     * 压缩模式
     */
    compress_mode: number | undefined;
    /**
     * 输出缓冲区大小
     */
    output_buf_size: number | undefined;
    /**
     * 输出数据
     */
    output_buf: Uint8Array | undefined;
}
class BmpConvertMessage {
    /**
     * 消息-bitmap图像转换
    */
    static MSG_BITMAP_CONVERT = "message_bitmap_convert"
    // /**
    //  * 消息-线程已完成
    // */
    // static MSG_FINISHED = "message_finished"
}
export class Result {
    // 大于0，意味着转码成功
    static RESULT_SUCCESS = 1;
    // 小于等于0, 视为转码失败，负数为错误码
    static RESULT_ERROR = -0xE00;
    static RESULT_ERROR_INVALID_PARAM = -0xE01;
    static RESULT_ERROR_IO_EXCEPTION = -0xE02;
}
class Key {
    static FUNC = "func"

    /*****************************************输入参数*********************************/

    /**
     * 输入数据(bitmap-像素-BGRA格式)
    */
    static IN_BUFFER = "in_buffer"
    /**
     * 转码算法
    */
    static FLAG = "flag"
    /**
     * 图像宽度
    */
    static WIDTH = "width"
    /**
     * 图像高度
    */
    static HEIGHT = "height"
    /**
     * 编码格式
    */
    static FORMAT = "format"




    /*****************************************输出结果参数*********************************/

    /**
    * 结果码
    * <p>
    * 说明:<br/>
    * 1. 小于等于0, 视为转码失败，负数为错误码<br/>
    * 2. 大于0，意味着转码成功
    * </p>
    */
    static RESULT = "result"
    /**
     * 算法类型
     */
    static ALGORITHM = "algorithm"
    /**
     * 输出数据大小
     */
    static OUTPUT_BUFFER_SIZE = "output_buffer_size"
    /**
     * 输出数据
     */
    static OUTPUT_BUFFER = "output_buffer"
    /**
     * 图像格式
     *  <p>
     * 说明: 从707N算法后，增加该字段，用于【不打包算法】的处理
     * </p>
     */
    static PIXEL_FORMAT = "pixel_format"
    /**
     * 压缩模式
     * <p>
     * 说明: 从707N算法后，增加该字段，用于【不打包算法】的处理
     * </p>
     */
    static COMPRESS_MODE = "compress_mode"
}
export class CallBack {
    onStart() { };
    onFinished(_result: ConversionResult) { };
}
export class BmpConvertManager {
    private workManager: WorkerManager | undefined;
    private isRunning = false;
    private messageCallback: ((msg: Record<string, any>) => void) | undefined
    constructor(workManager: WorkerManager) {
        this.workManager = workManager;
    }
    /**
     * bitmap图像转换
     * @param flag 转换类型
     * @param in_buffer bitmap图像数据(非JPG或者PNG图像数据)
     * @param width bitmap图像宽度
     * @param height bitmap图像高度
     * @param param 转换参数
     * @returns 是否成功运行
    */
    bitmapConvert(flag: BmpConvertType, in_buffer: Uint8Array, width: number, height: number, param: ConvertParam, callback: CallBack) {
        if (this.isRunning) {
            return false;
        }
        if (this.workManager?.run("workers/bmp_convert/index.js")) {
            this.isRunning = true;
            this.messageCallback = (msg: Record<string, any>) => {
                if (msg[Key.FUNC] === MessageConstant.MSG_START) {//work任务已完成
                    callback?.onStart();
                } else if (msg[Key.FUNC] === MessageConstant.MSG_FINISHED) {//work任务已完成
                    this.isRunning = false;
                    const result = msg[Key.RESULT]
                    const conversionResult = new ConversionResult();
                    conversionResult.result = result;
                    if (result >= Result.RESULT_SUCCESS) {
                        //转换结果成功
                        console.log("bitmapConvert success")
                        const algorithm = msg[Key.ALGORITHM];
                        const output_buf_size = msg[Key.OUTPUT_BUFFER_SIZE];
                        const pixel_format = msg[Key.PIXEL_FORMAT];
                        const compress_mode = msg[Key.COMPRESS_MODE];
                        const buffer = msg[Key.OUTPUT_BUFFER];
                        conversionResult.algorithm = algorithm;
                        conversionResult.output_buf_size = output_buf_size;
                        conversionResult.output_buf = new Uint8Array(buffer);
                        conversionResult.pixel_format = pixel_format;
                        conversionResult.compress_mode = compress_mode;
                    } else {
                        //转换结果失败
                        console.log("bitmapConvert fail")
                    }
                    if (this.messageCallback) {
                        this.workManager?.removeMessageCallback(this.messageCallback)
                        this.messageCallback = undefined
                    }
                    callback?.onFinished(conversionResult);
                }
            }
            this.workManager?.addMessageCallback(this.messageCallback)
            const messageObj: Record<string, any> = new Object();
            messageObj[Key.FUNC] = BmpConvertMessage.MSG_BITMAP_CONVERT;
            messageObj[Key.FLAG] = flag;
            messageObj[Key.IN_BUFFER] = in_buffer.buffer;//WorkerManager.postMessage()不支持Uint8Array,只支持ArrayBuffer
            messageObj[Key.WIDTH] = width;
            messageObj[Key.HEIGHT] = height;
            messageObj[Key.FORMAT] = param.format;

            this.workManager?.postMessage(messageObj)
            return true;
        } else {
            console.log("bitmapConvert worker run fail");
            return false;
        }
    }
    release() {
        if (this.isRunning) {//正在运行
            //暂停掉当前woker线程
            this.workManager?.terminate()
            if (this.messageCallback) {
                this.workManager?.removeMessageCallback(this.messageCallback)
                this.messageCallback = undefined
            }
            this.isRunning = false
        }
    }
}
